/**
 * 表单验证工具
 */

/**
 * 验证规则类型
 */
export interface ValidationRule {
  required?: boolean;
  message?: string;
  validator?: (value: any) => boolean | string;
  min?: number;
  max?: number;
  pattern?: RegExp;
  email?: boolean;
  phone?: boolean;
  url?: boolean;
  idCard?: boolean;
  password?: boolean;
}

/**
 * 验证结果类型
 */
export interface ValidationResult {
  valid: boolean;
  message?: string;
}

/**
 * 验证邮箱格式
 * @param email 邮箱地址
 * @returns 是否有效
 */
export const validateEmail = (email: string): boolean => {
  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  return emailRegex.test(email);
};

/**
 * 验证手机号格式（中国大陆）
 * @param phone 手机号
 * @returns 是否有效
 */
export const validatePhone = (phone: string): boolean => {
  const phoneRegex = /^1[3-9]\d{9}$/;
  return phoneRegex.test(phone);
};

/**
 * 验证身份证号格式（中国大陆）
 * @param idCard 身份证号
 * @returns 是否有效
 */
export const validateIdCard = (idCard: string): boolean => {
  const idCardRegex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  if (!idCardRegex.test(idCard)) return false;
  
  // 18位身份证校验码验证
  if (idCard.length === 18) {
    const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
    
    let sum = 0;
    for (let i = 0; i < 17; i++) {
      sum += parseInt(idCard[i]) * weights[i];
    }
    
    const checkCode = checkCodes[sum % 11];
    return idCard[17].toUpperCase() === checkCode;
  }
  
  return true;
};

/**
 * 验证URL格式
 * @param url URL地址
 * @returns 是否有效
 */
export const validateUrl = (url: string): boolean => {
  try {
    new URL(url);
    return true;
  } catch {
    return false;
  }
};

/**
 * 验证密码强度
 * @param password 密码
 * @param options 验证选项
 * @returns 验证结果
 */
export const validatePassword = (
  password: string,
  options: {
    minLength?: number;
    requireUppercase?: boolean;
    requireLowercase?: boolean;
    requireNumbers?: boolean;
    requireSpecialChars?: boolean;
  } = {}
): ValidationResult => {
  const {
    minLength = 8,
    requireUppercase = true,
    requireLowercase = true,
    requireNumbers = true,
    requireSpecialChars = true
  } = options;

  if (password.length < minLength) {
    return {
      valid: false,
      message: `密码长度至少${minLength}位`
    };
  }

  if (requireUppercase && !/[A-Z]/.test(password)) {
    return {
      valid: false,
      message: '密码必须包含大写字母'
    };
  }

  if (requireLowercase && !/[a-z]/.test(password)) {
    return {
      valid: false,
      message: '密码必须包含小写字母'
    };
  }

  if (requireNumbers && !/\d/.test(password)) {
    return {
      valid: false,
      message: '密码必须包含数字'
    };
  }

  if (requireSpecialChars && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
    return {
      valid: false,
      message: '密码必须包含特殊字符'
    };
  }

  return { valid: true };
};

/**
 * 验证中文姓名
 * @param name 姓名
 * @returns 是否有效
 */
export const validateChineseName = (name: string): boolean => {
  const nameRegex = /^[\u4e00-\u9fa5]{2,10}$/;
  return nameRegex.test(name);
};

/**
 * 验证银行卡号（中国大陆）
 * @param cardNumber 银行卡号
 * @returns 是否有效
 */
export const validateBankCard = (cardNumber: string): boolean => {
  // 移除空格和连字符
  const cleanNumber = cardNumber.replace(/[\s-]/g, '');
  
  // 检查长度（通常为16-19位）
  if (cleanNumber.length < 16 || cleanNumber.length > 19) {
    return false;
  }
  
  // Luhn算法验证
  let sum = 0;
  let isEven = false;
  
  for (let i = cleanNumber.length - 1; i >= 0; i--) {
    let digit = parseInt(cleanNumber[i]);
    
    if (isEven) {
      digit *= 2;
      if (digit > 9) {
        digit -= 9;
      }
    }
    
    sum += digit;
    isEven = !isEven;
  }
  
  return sum % 10 === 0;
};

/**
 * 验证IP地址
 * @param ip IP地址
 * @returns 是否有效
 */
export const validateIP = (ip: string): boolean => {
  const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  return ipRegex.test(ip);
};

/**
 * 验证端口号
 * @param port 端口号
 * @returns 是否有效
 */
export const validatePort = (port: number | string): boolean => {
  const portNum = typeof port === 'string' ? parseInt(port) : port;
  return portNum >= 1 && portNum <= 65535;
};

/**
 * 验证邮政编码（中国大陆）
 * @param postalCode 邮政编码
 * @returns 是否有效
 */
export const validatePostalCode = (postalCode: string): boolean => {
  const postalRegex = /^[1-9]\d{5}$/;
  return postalRegex.test(postalCode);
};

/**
 * 验证车牌号（中国大陆）
 * @param plateNumber 车牌号
 * @returns 是否有效
 */
export const validatePlateNumber = (plateNumber: string): boolean => {
  const plateRegex = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/;
  return plateRegex.test(plateNumber);
};

/**
 * 通用表单验证器
 * @param value 要验证的值
 * @param rules 验证规则
 * @returns 验证结果
 */
export const validateField = (value: any, rules: ValidationRule[]): ValidationResult => {
  for (const rule of rules) {
    // 必填验证
    if (rule.required && (value === undefined || value === null || value === '')) {
      return {
        valid: false,
        message: rule.message || '此字段为必填项'
      };
    }

    // 如果值为空且不是必填，跳过其他验证
    if (!rule.required && (value === undefined || value === null || value === '')) {
      continue;
    }

    // 长度验证
    if (typeof value === 'string') {
      if (rule.min !== undefined && value.length < rule.min) {
        return {
          valid: false,
          message: rule.message || `长度不能少于${rule.min}个字符`
        };
      }
      if (rule.max !== undefined && value.length > rule.max) {
        return {
          valid: false,
          message: rule.message || `长度不能超过${rule.max}个字符`
        };
      }
    }

    // 数值范围验证
    if (typeof value === 'number') {
      if (rule.min !== undefined && value < rule.min) {
        return {
          valid: false,
          message: rule.message || `值不能小于${rule.min}`
        };
      }
      if (rule.max !== undefined && value > rule.max) {
        return {
          valid: false,
          message: rule.message || `值不能大于${rule.max}`
        };
      }
    }

    // 正则表达式验证
    if (rule.pattern && typeof value === 'string' && !rule.pattern.test(value)) {
      return {
        valid: false,
        message: rule.message || '格式不正确'
      };
    }

    // 邮箱验证
    if (rule.email && typeof value === 'string' && !validateEmail(value)) {
      return {
        valid: false,
        message: rule.message || '邮箱格式不正确'
      };
    }

    // 手机号验证
    if (rule.phone && typeof value === 'string' && !validatePhone(value)) {
      return {
        valid: false,
        message: rule.message || '手机号格式不正确'
      };
    }

    // URL验证
    if (rule.url && typeof value === 'string' && !validateUrl(value)) {
      return {
        valid: false,
        message: rule.message || 'URL格式不正确'
      };
    }

    // 身份证验证
    if (rule.idCard && typeof value === 'string' && !validateIdCard(value)) {
      return {
        valid: false,
        message: rule.message || '身份证号格式不正确'
      };
    }

    // 密码验证
    if (rule.password && typeof value === 'string') {
      const passwordResult = validatePassword(value);
      if (!passwordResult.valid) {
        return {
          valid: false,
          message: rule.message || passwordResult.message
        };
      }
    }

    // 自定义验证器
    if (rule.validator) {
      const result = rule.validator(value);
      if (typeof result === 'string') {
        return {
          valid: false,
          message: result
        };
      }
      if (result === false) {
        return {
          valid: false,
          message: rule.message || '验证失败'
        };
      }
    }
  }

  return { valid: true };
};

/**
 * 验证整个表单
 * @param formData 表单数据
 * @param rules 验证规则对象
 * @returns 验证结果
 */
export const validateForm = (
  formData: Record<string, any>,
  rules: Record<string, ValidationRule[]>
): { valid: boolean; errors: Record<string, string> } => {
  const errors: Record<string, string> = {};
  let valid = true;

  for (const field in rules) {
    const result = validateField(formData[field], rules[field]);
    if (!result.valid) {
      valid = false;
      errors[field] = result.message || '验证失败';
    }
  }

  return { valid, errors };
};
